home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Game Programming in C++ - Start to Finish
/
GameProgrammingS.iso
/
Peon
/
PeonSDK-Win32-1.0.0.exe
/
{app}
/
PeonMain
/
source
/
SceneRenderer.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
2005-11-30
|
13KB
|
508 lines
#include "FileLogger.h"
#include "IniConfigReader.h"
#include "SceneRenderer.h"
namespace peon
{
SceneRenderer::SceneRenderer()
{
m_pOGLSurface = NULL;
m_pActiveCamera = NULL;
m_iDeviceWidth = 640;
m_iDeviceHeight= 480;
m_iBitsPerPixel= 16;
m_bWindowed = true;
}
SceneRenderer::~SceneRenderer()
{
unloadDevice();
}
bool SceneRenderer::loadDevice( IniConfigReader* pConfig )
{
m_iDeviceWidth = (int)pConfig->getInt("Application", "WindowWidth", 640);
m_iDeviceHeight = (int)pConfig->getInt("Application", "WindowHeight", 480);
m_iBitsPerPixel = (int)pConfig->getInt("Application", "WindowDepth", 16);
m_bWindowed = pConfig->getBool("Application", "Windowed", "TRUE");
Uint32 iFlags;
///////////// we set the common flags here
iFlags = SDL_OPENGL; // it's an openGL window
iFlags |= SDL_HWPALETTE; // exclusive access to hardware colour palette
iFlags |= SDL_RESIZABLE; // the window must be resizeable
const SDL_VideoInfo *pVideoInfo = SDL_GetVideoInfo(); // query SDL for information about our video hardware
if(pVideoInfo == NULL) // if this query fails
{
FileLogger::getSingleton().logFatal("Renderer", "Error querying video information");
return false;
}
if( !m_bWindowed )
{
iFlags |= SDL_FULLSCREEN;
}
//we set the system dependant flags here
if(pVideoInfo -> hw_available)
iFlags |= SDL_HWSURFACE;
else
iFlags |= SDL_SWSURFACE;
// Blitting is fast copying / moving /swapping of contiguous sections of memory
// more blitting info: http://www.csc.liv.ac.uk/~fish/HTML/blitzman/bm_blitter.html
if(pVideoInfo -> blit_hw) // is hardware blitting available
iFlags |= SDL_HWACCEL;
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // tell SDL that the GL drawing is going to be double buffered
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, m_iBitsPerPixel); // size of depth buffer
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0); // we aren't going to use the stencil buffer
SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0); // this and the next three lines set the bits allocated per pixel -
SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0); // - for the accumulation buffer to 0
SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
//log our information...for now just log the width x height x bit depth
//of our requested surface
char strOutput[1024];
sprintf(strOutput, "Renderer surface: (%d x %d x %d)", m_iDeviceWidth, m_iDeviceHeight,
m_iBitsPerPixel);
FileLogger::getSingleton().logInfo("Renderer", strOutput );
if(m_bWindowed)
{
sprintf(strOutput, "Renderer surface: applying windowed");
}else
sprintf(strOutput, "Renderer surface: applying fullscreen");
FileLogger::getSingleton().logInfo("Renderer", strOutput );
//This is the method which creates/generates our SDL_Surface
//according to the creation parameters we've set above. The
//SDL documentation is a good place to look for more information,
//but at the end of the day this should create our OpenGL
//surface.
m_pOGLSurface = SDL_SetVideoMode( m_iDeviceWidth, m_iDeviceHeight, m_iBitsPerPixel, iFlags );
if(NULL == m_pOGLSurface)
{
FileLogger::getSingleton().logError("Renderer", "Failed to create the OpenGL surface!");
return false;
}
glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
const char *glVendor = (const char *) glGetString(GL_VENDOR);
const char *glRenderer = (const char *) glGetString(GL_RENDERER);
const char *glVersion = (const char *) glGetString(GL_VERSION);
//const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
sprintf(strOutput, "Renderer Vendor: %s", glVendor );
FileLogger::getSingleton().logInfo("Renderer", strOutput );
sprintf(strOutput, "Renderer Stats: %s", glRenderer );
FileLogger::getSingleton().logInfo("Renderer", strOutput );
sprintf(strOutput, "Renderer Version: %s", glVersion );
FileLogger::getSingleton().logInfo("Renderer", strOutput );
//set some default OpenGL properties
glEnable( GL_TEXTURE_2D );
glDisable( GL_LIGHTING );
glShadeModel( GL_SMOOTH );
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glFrontFace( GL_CW );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
float fAspect = (float)m_iDeviceWidth / (float)m_iDeviceHeight;
m_pActiveCamera = new SceneCamera();
m_pActiveCamera->setPerspectiveProj( fAspect, 1.0f, 100.0f );
m_pActiveCamera->setViewMatrix( Vector3( 0.0f, 0.0f, 10.0f ),
Vector3( 0.0f, 0.0f, 0.0f ),
Vector3( 0.0f, 1.0f, 0.0f ) );
//since the Renderer object has been created, instantiate the CEGUI library
CEGUI::OpenGLRenderer* myRenderer = new CEGUI::OpenGLRenderer( 1024 );
//instantiate the CEGUI subsystem with the OpenGL renderer
new CEGUI::System(myRenderer);
return true;
}
void SceneRenderer::unloadDevice()
{
delete CEGUI::System::getSingletonPtr();
PEON_DELETE( m_pActiveCamera );
SDL_FreeSurface( m_pOGLSurface );
}
void SceneRenderer::flipDevice()
{
glFlush();
SDL_GL_SwapBuffers();
}
bool SceneRenderer::clearDevice()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
return true;
}
void SceneRenderer::drawPrim( DiffusePrim* pVertices, int count )
{
//push the current modelview matrix onto the matrix stack
glPushMatrix();
//push the current color information onto the attribute stack
glPushAttrib( GL_CURRENT_BIT );
glLoadIdentity();
//start pushing triangles through the pipeline
glBegin( GL_TRIANGLES );
for(int i = 0; i < count; i++)
{
//specify the diffuse color component of the vertex
glColor4f( pVertices[i].r, pVertices[i].g,
pVertices[i].b, pVertices[i].a );
//specify the position component of the vertex
glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
}
//finished
glEnd();
glPopAttrib();
glPopMatrix();
}
void SceneRenderer::drawPrim( DiffuseTexPrim* pVertices, int count )
{
//push the current modelview matrix onto the matrix stack
glPushMatrix();
//push the current color information onto the attribute stack
glPushAttrib( GL_CURRENT_BIT );
glLoadIdentity();
//start pushing triangles through the pipeline
glBegin( GL_TRIANGLES );
for(int i = 0; i < count; i++)
{
//specify the diffuse color component of the vertex
glColor4f( pVertices[i].r, pVertices[i].g,
pVertices[i].b, pVertices[i].a );
glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
//specify the position component of the vertex
glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
}
//finished
glEnd();
glPopAttrib();
glPopMatrix();
}
void SceneRenderer::drawPrim( NormalDiffuseTexPrim* pVertices, int count )
{
//push the current modelview matrix onto the matrix stack
glPushMatrix();
//push the current color information onto the attribute stack
glPushAttrib( GL_CURRENT_BIT );
glLoadIdentity();
//start pushing triangles through the pipeline
glBegin( GL_TRIANGLES );
for(int i = 0; i < count; i++)
{
glNormal3f( pVertices[i].nx, pVertices[i].ny, pVertices[i].nz );
//specify the diffuse color component of the vertex
glColor4f( pVertices[i].r, pVertices[i].g,
pVertices[i].b, pVertices[i].a );
glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
//specify the position component of the vertex
glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
}
//finished
glEnd();
glPopAttrib();
glPopMatrix();
}
void SceneRenderer::drawQuads( NormalDiffuseTexPrim* pVertices, int count )
{
OutputDebugString("drawing quads\n");
//push the current modelview matrix onto the matrix stack
glPushMatrix();
//push the current color information onto the attribute stack
glPushAttrib( GL_CURRENT_BIT );
glLoadIdentity();
//start pushing triangles through the pipeline
glBegin( GL_QUADS );
for(int i = 0; i < count; i++)
{
glNormal3f( pVertices[i].nx, pVertices[i].ny, pVertices[i].nz );
//specify the diffuse color component of the vertex
glColor4f( pVertices[i].r, pVertices[i].g,
pVertices[i].b, pVertices[i].a );
glTexCoord2f( pVertices[i].tu, pVertices[i].tv );
//specify the position component of the vertex
glVertex3f( pVertices[i].x, pVertices[i].y, pVertices[i].z );
}
//finished
glEnd();
glPopAttrib();
glPopMatrix();
}
void SceneRenderer::setLight(int light_slot, const SceneLight& oLight)
{
GLenum eLight = GL_LIGHT0;
switch( light_slot )
{
case 1:
eLight = GL_LIGHT1;
break;
case 2:
eLight = GL_LIGHT2;
break;
case 3:
eLight = GL_LIGHT3;
break;
case 4:
eLight = GL_LIGHT4;
break;
case 5:
eLight = GL_LIGHT5;
break;
case 6:
eLight = GL_LIGHT6;
break;
case 7:
eLight = GL_LIGHT7;
break;
}
float ambient[4];
float diffuse[4];
float position[4];
ambient[0] = oLight.m_vecAmbient.x;
ambient[1] = oLight.m_vecAmbient.y;
ambient[2] = oLight.m_vecAmbient.z;
ambient[3] = oLight.m_vecAmbient.w;
diffuse[0] = oLight.m_vecDiffuse.x;
diffuse[1] = oLight.m_vecDiffuse.y;
diffuse[2] = oLight.m_vecDiffuse.z;
diffuse[3] = oLight.m_vecDiffuse.w;
position[0] = oLight.m_vecDirection.x;
position[1] = oLight.m_vecDirection.y;
position[2] = oLight.m_vecDirection.z;
position[3] = oLight.m_vecDirection.w;
glLightfv( eLight, GL_AMBIENT, ambient ); // Set our ambience values (Default color without direct light)
glLightfv( eLight, GL_DIFFUSE, diffuse ); // Set our diffuse color (The light color)
glLightfv( eLight, GL_POSITION, position ); // This Sets our light position
glEnable( eLight ); // Turn this light on
//if we're setting a light, then at least we should
//enable lighting
glEnable( GL_LIGHTING );
glEnable( GL_COLOR_MATERIAL );
m_oLights[light_slot] = oLight;
}
SceneTexture* SceneRenderer::loadTexture( const String& strFilename, bool bAlpha,
bool bMipMaps, bool bRepeat)
{
SceneTexture* pTex = new SceneTexture();
pTex->loadImage( strFilename, bAlpha, bMipMaps, bRepeat );
return( pTex );
}
/*
void SceneRenderer::setTexture( SceneTexture* pTex )
{
glBindTexture(GL_TEXTURE_2D, pTex->getTex() );
}
*/
SceneFont* SceneRenderer::loadFont( int char_width, int char_height, int char_spacing )
{
SceneFont* pFont = new SceneFont();
pFont->loadFont( char_width, char_height, char_spacing );
return( pFont );
}
bool SceneRenderer::isExtensionSupported( const String& ext )
{
int pos = 0;
bool supported = false;
int n = (int)ext.length();
String extensions ((char *)glGetString(GL_EXTENSIONS));
while( !supported )
{
if ( extensions.compare(pos, n, ext) >= 0 ) // if the string `ext' is a part of the string `extensions'
{
return true;
}
pos = extensions.find(' ' , pos) + 1;
if( pos <= 0 )
return false;
}
return false;
}
/**
* http://www.devolution.com/pipermail/sdl/2000-September/030013.html
*/
void SceneRenderer::getScreenCapture()
{
SDL_Surface *temp;
unsigned char *pixels;
int i;
static int file_count = 0;
char strFileName[1024];
sprintf(strFileName, "screen_capture_%d.bmp", file_count);
temp = SDL_CreateRGBSurface(SDL_SWSURFACE, m_pOGLSurface->w, m_pOGLSurface->h, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
0x000000FF, 0x0000FF00, 0x00FF0000, 0
#else
0x00FF0000, 0x0000FF00, 0x000000FF, 0
#endif
);
if (temp == NULL)
return;
pixels = new unsigned char[3 * m_pOGLSurface->w * m_pOGLSurface->h];
if (pixels == NULL)
{
SDL_FreeSurface(temp);
return;
}
glReadPixels(0, 0, m_pOGLSurface->w, m_pOGLSurface->h, GL_RGB, GL_UNSIGNED_BYTE, pixels);
for (i=0; i<m_pOGLSurface->h; i++)
memcpy(((char *) temp->pixels) + temp->pitch * i, pixels + 3*m_pOGLSurface->w * (m_pOGLSurface->h-i-1), m_pOGLSurface->w*3);
PEON_DELETE_ARRAY( pixels );
SDL_SaveBMP(temp, strFileName);
SDL_FreeSurface(temp);
file_count++;
}
void SceneRenderer::getProjectionMatrix( Matrix44& pMat )
{
//glGetFloatv( GL_PROJECTION_MATRIX, pMat.m );
}
void SceneRenderer::getModelViewMatrix( Matrix44& pMat )
{
//glGetFloatv( GL_MODELVIEW_MATRIX, pMat.m );
}
}